package com.ChenYaRou.www.utils;


import java.lang.reflect.Field;
import java.time.LocalDateTime;

/**
 * @ClassName GenerateSql
 * @Description TODO
 * @Author 86183
 * @Date 2022/4/29 0:51
 * @Version 1.0
 **/
public class GenerateSql {

    private static volatile GenerateSql generateSql;
    private String node=" , ";
    private final StringBuilder stringBuilder=new StringBuilder();
    private GenerateSql(){}
    public static GenerateSql getInstance(){
        if(generateSql==null){
            synchronized (GenerateSql.class){
                if(generateSql==null){
                    generateSql=new GenerateSql();
                }
            }
        }
        return generateSql;
    }

    /*
     * select * from (table) where (limit)
     * insert into (table) (字段名数组)values(值数组);
     * update (table) set 字段名数组[0] set 值数组[0],....数组.length where (limit)
     * delete from (table) where (limit)
     * */

    /**
     * 插入语句
     * @param object 插入对象
     * @param <K> 对象类型
     * @return 插入语句
     * @throws IllegalAccessException 非法访问异常
     */
    public  <K> String insert(K object) throws IllegalAccessException {
        node=", ";
        stringBuilder.delete(0,stringBuilder.length());
        Class<?> tClass = object.getClass();
        String className = tClass.toString();
        Field[] declaredFields = tClass.getDeclaredFields();
        String s = className.toLowerCase();
        stringBuilder.append("insert into ").append(s.substring(s.lastIndexOf(".")+1)).append("( ");
        for (Field declaredField : declaredFields) {
            String fieldName = declaredField.getName();
            if("id".equals(fieldName)){continue;}
            stringBuilder.append(fieldName).append(node);
        }
        stringBuilder.delete(stringBuilder.lastIndexOf(node),stringBuilder.length()).append(")values( ");
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Object value = declaredField.get(object);
            if(value!=null){
                if(value instanceof String ||value instanceof LocalDateTime){
                    value="'"+value+"'";
                }
                stringBuilder.append(" ").append(value).append(node);
            }
        }
        stringBuilder.delete(stringBuilder.lastIndexOf(node),stringBuilder.length()).append(")");
        return stringBuilder.toString();

    }

    /**
     *update (table) set 字段名数组[0] set 值数组[0],....数组.length where (limit)
     * @param newObject 要更新的值所存有的对象
     * @param <K> 对象类型
     * @param limitObject 含有限制条件的对象
     * @return update语句
     */
    public <K> String update(K newObject,K limitObject) throws IllegalAccessException {
        stringBuilder.delete(0,stringBuilder.length());
        Class<?> tClass = newObject.getClass();
        String className = tClass.toString();
        /*获得成员变量集合*/
        Field[] declaredFields = tClass.getDeclaredFields();
        String s = className.toLowerCase();
        stringBuilder.append("update ").append(s.substring(s.lastIndexOf(".")+1)).append(" set");
        node=" , ";
        operateFields(declaredFields,newObject,node);
        stringBuilder.delete(stringBuilder.lastIndexOf(node),stringBuilder.length());
        if(limitObject!=null){
            node=" and ";
            stringBuilder.append(" where ");
            operateFields(declaredFields,limitObject,node);
            stringBuilder.delete(stringBuilder.lastIndexOf(node),stringBuilder.length());
        }
        return  stringBuilder.toString();
    }

    private <K> void operateFields(Field[] declaredFields,K object,String node) throws IllegalAccessException {
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Object value = declaredField.get(object);
            if(value!=null){
                String memberName=declaredField.getName();
                if(value instanceof String || value instanceof LocalDateTime){
                    value="'"+value+"'";
                }
                stringBuilder.append(" ").append(memberName).append(" = ").append(value).append(node);
            }
        }
    }


    /**
     *自动生成select语句
     * @param limitObject 只赋值条件的对象
     * @return select语句
     * @throws IllegalAccessException
     */

    public <K> String select(K limitObject) throws IllegalAccessException {
        node=" and ";
        Class<?> tClass =limitObject.getClass();
        selectFirstSentence(tClass.toString().toLowerCase());
        Field[] declaredFields = tClass.getDeclaredFields();
        operateFields(declaredFields,limitObject,node);
        stringBuilder.append(" '1'='1'");
        return stringBuilder.toString();
    }

    /**
     * 使用%模糊查询
     * @param object
     * @param <K>
     * @return
     * @throws IllegalAccessException
     */
    public <K> String fuzzySelect(K object) throws IllegalAccessException {
        //select * from K where ?=%?%
        stringBuilder.delete(0,stringBuilder.length());
        selectFirstSentence(object.getClass().toString().toLowerCase());
        Field[] declaredFields = object.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Object value = declaredField.get(object);
            if(value!=null){
                String memberName=declaredField.getName();
                value="'%"+value+"%'";
                stringBuilder.append(memberName).append(" like ").append(value);
            }
        }
        return stringBuilder.toString();
    }

    /**
     * select语句的头部
     * @param s
     */
    private void selectFirstSentence(String s){
        stringBuilder.delete(0,stringBuilder.length());
        stringBuilder.append("select * from ").append(s.substring(s.lastIndexOf(".")+1)).append(" where ");
    }

    /**
     * 查询所有时的语句
     * @param object 对象
     * @param <K>
     * @return
     */
    public <K> String selectAll(K object){
        String tClass = object.getClass().getName();
        return stringBuilder.delete(0,stringBuilder.length()).append("select * from ").
                append(tClass.substring(tClass.lastIndexOf(".")+1)).append(" where 1=1").toString();
    }

}
